`include "PRV564Config.v"
`include "PRV564Define.v"

//----------------------------------------------------------
//AXI_axcache 全部置零  未启用AXI总线中的buffer和cache功能
//AXI_axprot  全部置零	未启用访问权限功能
//AXI_axqos	  全部置零  未启用传输优先级功能
//AXI_axregion全部置零  未启用访存区域选择功能
//AXI_axuser  用户定义的信号暂不使用
//
//回复信号的优先级 SFR > Decode_ERROR > B > RD
//
//-------------------------------------------------------------


module FIB2AXI #(
	parameter AXI_ID_WIDTH 	= 8,
	parameter AXI_ADDR_WID  = 32,
	parameter AXI_AXCACHE 	= 4'd0,
	parameter AXI_AXPROT  	= 3'd0,
	parameter AXI_AXQOS		= 4'd0,
	parameter AXI_AXREGION	= 4'd0
)
(
    input  wire             		CLKi,
    input  wire             		RSTi,
//--------------------FIB interface----------------
    output  reg             		FIBo_ACK,         //ack for valid (read a new access from FIFO)
    input  wire             		FIBi_V,           //request acknowledge
    input  wire [7:0]       		FIBi_ID,
    input  wire [7:0]       		FIBi_CMD,
    input  wire [3:0]       		FIBi_BURST,
    input  wire [3:0]       		FIBi_SIZE,
    input  wire [`PADR-1:0] 		FIBi_ADDR,      
    input  wire [`XLEN-1:0] 		FIBi_DATA,
    //            reply to master
    output  reg [7:0]       		FIBo_ID,
    output  reg [7:0]       		FIBo_RPL,			//应答
    output  reg             		FIBo_WREN,
    input  wire             		FIBi_FULL,         //result FIFO is FULL, can not write
//  output  reg             		FIBo_ADDR,
    output  reg [`XLEN-1:0] 		FIBo_DATA,
//------------------SFR interface------------------------
    //        SFR : Special Function Register, 是核心私有的寄存器
    // SFR operation Timing:
    //                 |<-Read operation ->|<-Write Operation->|<-No operation
    //  CLK       :____/----\____/----\____/----\____/----\____/----\____/----\
    //  SFRi_ADDR :----<      ADDR0       ><       ADDR1       >---------------
    //  SFRi_DATA :------------------------<       DATA1       >---------------
    //  SFRi_CS   :____/---------------------------------------\_______________
    //  SFRi_WR   :________________________/-------------------\_______________
    //  SFRo_DATA :--------------<  DATA0  >-----------------------------------
	//
    output  reg [`PADR-1:0] 		FIBo_SFRi_ADDR,
    output  reg [`XLEN-1:0] 		FIBo_SFRi_DATA,
    output  reg             		FIBo_SFRi_CS,            //SFR select
    output  reg             		FIBo_SFRi_WR,            //write to SFR
    input  wire [`XLEN-1:0] 		FIBi_SFRo_DATA,
//-------------------AXI interface---------------------
//-------------------写地址通道-----------------------
    output reg [AXI_ID_WIDTH-1:0]  	FIBo_AXI_awid,
    output reg [`PADR-1:0]    		FIBo_AXI_awaddr,
    output reg [7:0]               	FIBo_AXI_awlen,
    output reg [2:0]               	FIBo_AXI_awsize,
    output reg [1:0]               	FIBo_AXI_awburst,
//  output reg                     	FIBo_AXI_awlock,
//  output reg [3:0]               	FIBo_AXI_awcache,
//  output reg [2:0]               	FIBo_AXI_awprot,
//  output reg [3:0]               	FIBo_AXI_awqos,
//  output reg [3:0]               	FIBo_AXI_awregion,
//  output reg [AWUSER_WIDTH-1:0]  	FIBo_AXI_awuser,
    output reg                     	FIBo_AXI_awvalid,
    input  wire                     FIBi_AXI_awready,
//---------------------写数据通道-----------------------------
    output reg [`XLEN-1:0]  		FIBo_AXI_wdata,
    output reg [7:0]  				FIBo_AXI_wstrb,
    output reg                     	FIBo_AXI_wlast,
//  output reg [WUSER_WIDTH-1:0]   	FIBo_AXI_wuser,
    output reg                     	FIBo_AXI_wvalid,
    input  wire                     FIBi_AXI_wready,
//----------------------写回复通道-------------------------------	
    input  wire [AXI_ID_WIDTH-1:0]  FIBi_AXI_bid,
    input  wire [1:0]               FIBi_AXI_bresp,
//  input  wire [BUSER_WIDTH-1:0]   FIBi_AXI_buser,
    input  wire                     FIBi_AXI_bvalid,
    output wire                     FIBo_AXI_bready,
//---------------------读地址通道-----------------------------------	
    output reg [AXI_ID_WIDTH-1:0]   FIBo_AXI_arid,
    output reg [`PADR-1:0]    		FIBo_AXI_araddr,
    output reg [7:0]               	FIBo_AXI_arlen,
    output reg [2:0]               	FIBo_AXI_arsize,
    output reg [1:0]               	FIBo_AXI_arburst,
//  output reg                     	FIBo_AXI_arlock,
//  output reg [3:0]               	FIBo_AXI_arcache,
//  output reg [2:0]               	FIBo_AXI_arprot,
//  output reg [3:0]               	FIBo_AXI_arqos,
//  output reg [3:0]               	FIBo_AXI_arregion,
//  output reg [ARUSER_WIDTH-1:0]  	FIBo_AXI_aruser,
    output reg                     	FIBo_AXI_arvalid,
    input  wire                     FIBi_AXI_arready,
//----------------------读数据通道----------------------------------
    input  wire [AXI_ID_WIDTH-1:0]  FIBi_AXI_rid,
    input  wire [`XLEN-1:0]  		FIBi_AXI_rdata,
    input  wire [1:0]               FIBi_AXI_rresp,
    input  wire                     FIBi_AXI_rlast,
//  input  wire [RUSER_WIDTH-1:0]   FIBi_AXI_ruser,
    input  wire                     FIBi_AXI_rvalid,
    output wire                     FIBo_AXI_rready
);

//===========================================================================================
//
//====================================内部信号定义===========================================
//

//-----------------------------FIB指令译码--------------------------------------------
	wire 							op_NOOP;					//无操作
	wire 							op_SIGR;					//单次读操作
	wire 							op_SIGW;					//单次写操作
	wire 							op_SEQR;					//连续读操作
	wire 							op_SEQW;					//连续写操作
	wire 							op_WAPR;					//回卷读操作
	wire 							op_WAPW;					//回卷写操作
	wire 							op_AMOR;					//原子读操作
	wire 							op_AMOW;					//原子写操作
	wire 							op_SEQE;					//连续传输结束操作
	wire 							op_LR;
	wire 							op_SC;
	wire 							op_AMOSWAP;
	wire 							op_AMOADD;
	wire 							op_AMOXOR;
	wire 							op_AMOAND;
	wire 							op_AMOOR;
	wire 							op_AMOMIN;
	wire 							op_AMOMAX;
	wire 							op_AMOMINU;
	wire 							op_AMOMAXU;
	wire 							op_DEC_ERR;				//译码出错
	


//---------------数据路由---------------------------------------------------------

//FIB工作状态  便于CMD = SEQE 时数据的路由

	reg 		[4:0] 				FIB_state;
	
	localparam IDLE_s 					= 5'd0;								//空闲
	localparam SFR_W_s 					= 5'd1;								//空闲	
	localparam SFR_R_s 					= 5'd2;								//空闲	
	localparam SFR_B_s 					= 5'd3;								//空闲		
	localparam GENERAL_W_WA_S 			= 5'd4;								//常规写状态
	localparam GENERAL_W_WD_S 			= 5'd5;
	localparam GENERAL_W_B_S 			= 5'd6;	
										  
	localparam GENERAL_R_RA_S 			= 5'd7;								//常规读状态
	localparam GENERAL_R_B_S 			= 5'd8;	
										  
	localparam SEQW_WA_s 				= 5'd9;								//连续写 写入地址
	localparam SEQW_WD_s 				= 5'd10;								//连续写状态
	localparam SEQW_B_s 				= 5'd11;								//连续写状态
	localparam SEQR_RA_s 				= 5'd12;								//连续写状态
	localparam SEQR_B_s 				= 5'd13;								//连续写状态	
	localparam AMO_RA_s					= 5'd14;								//AMO操作状态
	localparam AMO_RB_s					= 5'd15;								//AMO操作状态
	localparam AMO_WA_s					= 5'd16;								//AMO操作状态
	localparam AMO_WD_s					= 5'd17;								//AMO操作状态
	localparam AMO_WB_s					= 5'd18;								//AMO操作状态
	
	localparam DEC_ERR_s				= 5'd19;								//AMO操作状态	

//-------------------------------各通道选通信号-------------------------------------------------
	wire 						FIB_RA_access;				//访问AXI读地址通道选通信号
	wire 						FIB_WA_access;				//访问AXI写地址通道选通信号
	wire 						FIB_WD_access;				//访问AXI写数据通道选通信号	
	
//-----------------------CMD格式转换----------------------------------------------------------
	reg 	[7:0] 				FIBo_AXI_axlen_tem;
	wire 	[1:0] 				FIBo_AXI_axburst_tem;
	wire 						FIBo_AXI_axlock_tem;
	reg 	[7:0] 				AXI_WSTRB;					//字节掩码
	
//-----------------------各通道应答信号----------------------------------------	
	reg 						FIBo_WREN_ready;
	
	reg 	[7:0] 				AXI_BRPL;					//AXI反馈的传输状态信号
	reg 	[7:0] 				AXI_RRPL;					//AXI反馈的传输状态信号

//----------------------------访问SFR-----------------------------------------------
//访问SFR指令ID寄存器组
	reg		[AXI_ID_WIDTH-1:0]	SFR_ID_reg;
	
	
//------------------------------AMO操作------------------------------------------------
//FIB直接输入到AMO操作模块的数据寄存器组
	reg 	[`XLEN-1:0]			AMO_bo_data;
	reg 	[2:0]				AMO_bo_awsize;
	reg 	[`XLEN-1:0]			AMO_bo_awaddr;
	reg 	[7:0]				AMO_bo_wstrb;	
	reg 	[8:0]				AMO_bo_CMD;
	reg 	[AXI_ID_WIDTH-1:0]	AMO_bo_ID;
	reg 						AMO_bo_valid;


//AMO读操作返回的数据寄存器组
	reg 	[`XLEN-1:0]			AMO_ao_data;
	reg 						AMO_ao_valid;


//AMO操作后返回到core的数据寄存器组
    reg 	[AXI_ID_WIDTH-1:0]  AMO_Feedback_ID;
    reg 	[`XLEN-1:0] 	    AMO_Feedback_data;
	reg							AMO_Feedback_valid;

	
//AMO操作后写入到memory的数据寄存器组
	reg 	[`XLEN-1:0]			AMO_TX_data;
	reg 	[2:0]				AMO_TX_awsize;
	reg 	[`XLEN-1:0]			AMO_TX_awaddr;
	reg 	[7:0]				AMO_TX_wstrb;		
	reg 	[AXI_ID_WIDTH-1:0]	AMO_TX_ID;
	reg 						AMO_TX_valid;

//----------------------------------LR SC指令发出状态--------------------------------------
//LR指令发送记录标志位
	reg							LR_sent_flag;
	reg 	[AXI_ID_WIDTH-1:0]	LR_sent_ID;


//SC指令发送记录标志位
	reg							SC_sent_flag;
	reg 	[AXI_ID_WIDTH-1:0]	SC_sent_ID;

	
//--------------------------------AMO操作电路-------------------------------------------------
//经过掩码后的有效数据
	wire 	[`XLEN-1:0]  		sourse1;				//输入到AMO运算电路的数据
	wire 	[`XLEN-1:0]  		sourse2;				//输入到AMO运算电路的数据
	
//检测数据的符号
	reg 						sourse1_Symbol;			//输入到AMO运算电路的数据符号位
	reg 						sourse2_Symbol;			//输入到AMO运算电路的数据符号位

//AMO运算电路
	wire 	[`XLEN-1:0]			result1;				//写回memory
	wire 	[`XLEN-1:0]			result2;				//返回core
	wire 	[`XLEN-1:0]			data_AMOSWAP;
	wire 	[`XLEN-1:0]			data_AMOADD;
	wire 	[`XLEN-1:0]			data_AMOXOR;
	wire 	[`XLEN-1:0]			data_AMOAND;
	wire 	[`XLEN-1:0]			data_AMOOR;
	wire 	[`XLEN-1:0]			data_AMOMIN;
	wire 	[`XLEN-1:0]			data_AMOMAX;
	wire 	[`XLEN-1:0]			data_AMOMINU;
	wire 	[`XLEN-1:0]			data_AMOMAXU;	
	

//===========================================================================================
//
//====================================FIB指令译码===========================================
//
assign op_NOOP 		= (FIBi_CMD == `FIB_CMD_NOOP) 	? 1'b1 : 1'b0;
assign op_SIGR 		= (FIBi_CMD == `FIB_CMD_SIGR) 	? 1'b1 : 1'b0;
assign op_SIGW 		= (FIBi_CMD == `FIB_CMD_SIGW) 	? 1'b1 : 1'b0;
assign op_SEQR 		= (FIBi_CMD == `FIB_CMD_SEQR) 	? 1'b1 : 1'b0;
assign op_SEQW 		= (FIBi_CMD == `FIB_CMD_SEQW) 	? 1'b1 : 1'b0;
assign op_WAPR 		= (FIBi_CMD == `FIB_CMD_WAPR) 	? 1'b1 : 1'b0;
assign op_WAPW 		= (FIBi_CMD == `FIB_CMD_WAPW) 	? 1'b1 : 1'b0;
assign op_AMOR 		= (FIBi_CMD == `FIB_CMD_AMOR) 	? 1'b1 : 1'b0;
assign op_AMOW 		= (FIBi_CMD == `FIB_CMD_AMOW) 	? 1'b1 : 1'b0;
assign op_SEQE 		= (FIBi_CMD == `FIB_CMD_SEQE) 	? 1'b1 : 1'b0;
assign op_LR 		= (FIBi_CMD == `FIB_CMD_LR) 	? 1'b1 : 1'b0;
assign op_SC 		= (FIBi_CMD == `FIB_CMD_SC) 	? 1'b1 : 1'b0;
assign op_AMOSWAP 	= (FIBi_CMD == `FIB_CMD_AMOSWAP)? 1'b1 : 1'b0;
assign op_AMOADD 	= (FIBi_CMD == `FIB_CMD_AMOADD) ? 1'b1 : 1'b0;
assign op_AMOXOR 	= (FIBi_CMD == `FIB_CMD_AMOXOR) ? 1'b1 : 1'b0;
assign op_AMOAND 	= (FIBi_CMD == `FIB_CMD_AMOAND) ? 1'b1 : 1'b0;
assign op_AMOOR 	= (FIBi_CMD == `FIB_CMD_AMOOR) 	? 1'b1 : 1'b0;
assign op_AMOMIN 	= (FIBi_CMD == `FIB_CMD_MIN) 	? 1'b1 : 1'b0;
assign op_AMOMAX 	= (FIBi_CMD == `FIB_CMD_MAX) 	? 1'b1 : 1'b0;
assign op_AMOMINU 	= (FIBi_CMD == `FIB_CMD_MINU) 	? 1'b1 : 1'b0;
assign op_AMOMAXU 	= (FIBi_CMD == `FIB_CMD_MAXU) 	? 1'b1 : 1'b0;

assign op_DEC_ERR = (!(op_NOOP|op_SIGR|op_SIGW|op_SEQR|op_SEQW|op_WAPR|op_WAPW|op_AMOR|op_AMOW|op_SEQE|op_LR|op_SC|op_AMOSWAP|op_AMOADD|op_AMOXOR|op_AMOAND|op_AMOOR|op_AMOMIN|op_AMOMAX|op_AMOMINU|op_AMOMAXU)) ? 1'b1 : 1'b0; //解码出错

//===========================================================================================
//
//====================================数据路由===========================================
//
//FIB工作状态  便于CMD = SEQE 时数据的路由

always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIB_state <= IDLE_s;
//		$display("FIB_state is IDLE_s");
		end
	else begin
		case(FIB_state) 
			IDLE_s 			: begin
								if(FIBi_V && !FIBi_FULL) begin
									if(op_SIGW & (FIBi_ADDR & `SFR_ADDR_MASK) == `SFR_ADDR_SEG) begin
										FIB_state <= SFR_W_s;
//										$display("FIB_state is SFR_W_s");
										end
									else if(op_SIGR & (FIBi_ADDR & `SFR_ADDR_MASK) == `SFR_ADDR_SEG) begin
										FIB_state <= SFR_R_s;
//										$display("FIB_state is SFR_R_s");
										end
									else if(op_SIGW|op_AMOW|op_SC|op_WAPW) begin
										FIB_state <= GENERAL_W_WA_S;
//										$display("FIB_state is GENERAL_W_WA_S");
										end
									else if(op_SIGR|op_WAPR|op_AMOR|op_LR) begin
										FIB_state <= GENERAL_R_RA_S;
//										$display("FIB_state is GENERAL_R_RA_S");
										end
									else if(op_SEQR) begin
										FIB_state <= SEQR_RA_s;
//										$display("FIB_state is SEQR_RA_s");
										end
									else if(op_SEQW) begin
										FIB_state <= SEQW_WA_s;
//										$display("FIB_state is SEQW_WA_s");
										end
									else if(op_AMOSWAP|op_AMOADD|op_AMOXOR|op_AMOAND|op_AMOOR|op_AMOMIN|op_AMOMAX|op_AMOMINU|op_AMOMAXU) begin
										FIB_state <= AMO_RA_s;
//										$display("FIB_state is AMO_RA_s");
										end
									else if(op_DEC_ERR) begin
										FIB_state <= DEC_ERR_s;
//										$display("FIB_state is DEC_ERR_s");
										end
									else begin
										FIB_state <= IDLE_s;
//										$display("FIB_state is IDLE_s");
										end
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			SFR_W_s			:begin
								FIB_state <= SFR_B_s;
//								$display("FIB_state is SFR_B_s");
								end									
			SFR_R_s			:begin
								FIB_state <= SFR_B_s;
//								$display("FIB_state is SFR_B_s");
								end	
			SFR_B_s			:begin
								FIB_state <= IDLE_s;
//								$display("FIB_state is IDLE_s");
								end								
			GENERAL_W_WA_S	:begin
								if(FIBi_AXI_awready) begin
									FIB_state <= GENERAL_W_WD_S;
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			GENERAL_W_WD_S	:begin
									FIB_state <= GENERAL_W_B_S;
								end
			GENERAL_W_B_S	:begin 
								if(FIBi_AXI_bvalid & FIBo_WREN_ready) begin
									FIB_state <= IDLE_s;
//									$display("FIB_state is IDLE_s");
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			GENERAL_R_RA_S	:begin
									FIB_state <= GENERAL_R_B_S;
								end
			GENERAL_R_B_S	:begin 
								if(FIBi_AXI_rvalid & FIBo_WREN_ready) begin
									FIB_state <= IDLE_s;
//									$display("FIB_state is IDLE_s");
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			SEQW_WA_s		:begin
								if(FIBi_AXI_awready) begin
									FIB_state <= SEQW_WD_s;
									end	
								else begin
									FIB_state <= FIB_state;
									end
								end
			SEQW_WD_s		:begin
								if(FIBo_AXI_wvalid & FIBi_AXI_wready) begin
									if(op_SEQE) begin
										FIB_state <= SEQW_B_s;
//										$display("FIB_state is SEQW_B_s");
										end
									else begin
										FIB_state <= FIB_state;
										end
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			SEQW_B_s		:begin 
								if(FIBi_AXI_bvalid & FIBo_WREN_ready) begin
									FIB_state <= IDLE_s;
//									$display("FIB_state is IDLE_s");
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			SEQR_RA_s		:begin
									FIB_state <= SEQR_B_s;
								end	
			SEQR_B_s		:begin 
								if(FIBi_AXI_rvalid & FIBi_AXI_rlast & FIBo_WREN_ready) begin
									FIB_state <= IDLE_s;
//									$display("FIB_state is IDLE_s");
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			AMO_RA_s		:begin
									FIB_state <= AMO_RB_s;
								end	
			AMO_RB_s		:begin
								if(AMO_TX_valid) begin
									FIB_state <= AMO_WA_s;		
//									$display("FIB_state is AMO_WA_s");
									end	
								else begin
									FIB_state <= FIB_state;
									end
								end
			AMO_WA_s		:begin
								if(FIBi_AXI_awready) begin
									FIB_state <= AMO_WD_s;
									end
								else begin
									FIB_state <= FIB_state;
									end
								end	
			AMO_WD_s		:begin
									FIB_state <= AMO_WB_s;
								end	
			AMO_WB_s		:begin 
								if(FIBi_AXI_bvalid & FIBo_WREN_ready) begin
									FIB_state <= IDLE_s;
//									$display("FIB_state is IDLE_s");
									end
								else begin
									FIB_state <= FIB_state;
									end
								end
			DEC_ERR_s		:begin 
								FIB_state <= IDLE_s;
//								$display("FIB_state is IDLE_s");
								end
			default			:begin
								FIB_state <= IDLE_s;
//								$display("FIB_state is IDLE_s");
								end
		endcase
		end
	end

//-----------------------------------------------------------------------------------------------------
//---------------------------------------各通道导通信号------------------------------------------------	


assign FIB_RA_access = (FIB_state == IDLE_s && ((op_SIGR && ((FIBi_ADDR & `SFR_ADDR_MASK) != `SFR_ADDR_SEG))|op_WAPR|op_AMOR|op_LR|op_SEQR|op_AMOSWAP|op_AMOADD|op_AMOXOR|op_AMOAND|op_AMOOR|op_AMOMIN|op_AMOMAX|op_AMOMINU|op_AMOMAXU));
assign FIB_WA_access = (FIB_state == IDLE_s && ((op_SIGW && ((FIBi_ADDR & `SFR_ADDR_MASK) != `SFR_ADDR_SEG))|op_AMOW|op_SC|op_WAPW|op_SEQW));
assign FIB_WD_access = (FIB_state == GENERAL_W_WD_S || FIB_state == SEQW_WD_s);
	
//-----------------------------------------------------------------------------------------------------
//---------------------------------LR SC指令发送记录标志-----------------------------------------------	
//LR指令发送记录标志
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		LR_sent_flag 		<= 'd0;
		LR_sent_ID  		<= 'd0;
		end
	else if(FIBi_V) begin
		if(op_LR) begin
			LR_sent_flag 	<= FIBi_V;
			LR_sent_ID  	<= FIBi_ID;
//			$display("Start of LR transmission");
			end
		else if(op_SC && FIB_state == IDLE_s ) begin
			LR_sent_flag 	<= 'd0;
			LR_sent_ID  	<= 'd0;
//			$display("End of LR transmission");
			end	
		else begin
			LR_sent_flag 	<= LR_sent_flag;
			LR_sent_ID  	<= LR_sent_ID;
			end	
		end
	else begin
		LR_sent_flag 	<= LR_sent_flag;
		LR_sent_ID  	<= LR_sent_ID;
		end	
	end

//SC指令发送记录标志
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		SC_sent_flag 		<= 'd0;
		SC_sent_ID  		<= 'd0;
		end
	else if(FIBi_V) begin
		if(op_SC) begin
			SC_sent_flag 	<= FIBi_V;
			SC_sent_ID  	<= FIBi_ID;
//			$display("Start of SC transmission");
			end
		else if(FIBi_AXI_bvalid && SC_sent_flag) begin
			SC_sent_flag 	<= 'd0;
			SC_sent_ID  	<= 'd0;
//			$display("End of SC transmission");
			end	
		else begin
			SC_sent_flag 	<= SC_sent_flag;
			SC_sent_ID  	<= SC_sent_ID;
			end	
		end
	else begin
		SC_sent_flag 	<= SC_sent_flag;
		SC_sent_ID  	<= SC_sent_ID;
		end	
	end	
	
//------------------------------------------------------------------------------------------------
//---------------------------------数据格式转换电路-----------------------------------------------
//
//突发长度转换电路 FIBi_BURST --> FIBo_AXI_axlen
always@(*) begin
	case(FIBi_BURST[3:0]) 
		4'd0 	: begin FIBo_AXI_axlen_tem = 8'b00000000; end
		4'd1 	: begin FIBo_AXI_axlen_tem = 8'b00000001; end
		4'd2 	: begin FIBo_AXI_axlen_tem = 8'b00000011; end
		4'd3 	: begin FIBo_AXI_axlen_tem = 8'b00000111; end
		4'd4 	: begin FIBo_AXI_axlen_tem = 8'b00001111; end
		4'd5 	: begin FIBo_AXI_axlen_tem = 8'b00011111; end
		4'd6 	: begin FIBo_AXI_axlen_tem = 8'b00111111; end
		4'd7 	: begin FIBo_AXI_axlen_tem = 8'b01111111; end
		4'd8 	: begin FIBo_AXI_axlen_tem = 8'b11111111; end
		default : begin FIBo_AXI_axlen_tem = 8'b00000000; end
	endcase
	end

//突发类型转换电路 
assign FIBo_AXI_axburst_tem = (op_WAPR | op_WAPW) ?  2'b10 : 2'b01;  //回卷读写 递增读写

//FIBo_AXI_axlock_tem 锁定总线信号生成
assign FIBo_AXI_axlock_tem = (op_LR | op_SC) ? 1'b1 : 1'b0;

//AXI_WSTRB	写数据字节掩码
always@(*) begin
	case(FIBi_SIZE)
		4'd0	: begin
					case(FIBi_ADDR[2:0])
						3'd0	: begin AXI_WSTRB = 8'b00000001; end
						3'd1	: begin AXI_WSTRB = 8'b00000010; end
						3'd2	: begin AXI_WSTRB = 8'b00000100; end
						3'd3	: begin AXI_WSTRB = 8'b00001000; end
						3'd4	: begin AXI_WSTRB = 8'b00010000; end
						3'd5	: begin AXI_WSTRB = 8'b00100000; end
						3'd6	: begin AXI_WSTRB = 8'b01000000; end
						3'd7	: begin AXI_WSTRB = 8'b10000000; end
						default	: begin AXI_WSTRB = 8'b00000000; end
					endcase
					end
		4'd1	: begin 
					case(FIBi_ADDR[2:1]) 
						2'd0	: begin AXI_WSTRB = 8'b00000011; end
						2'd1	: begin AXI_WSTRB = 8'b00001100; end
						2'd2	: begin AXI_WSTRB = 8'b00110000; end
						2'd3	: begin AXI_WSTRB = 8'b11000000; end
						default	: begin AXI_WSTRB = 8'b00000000; end
					endcase
					end
		4'd2	: begin
					case(FIBi_ADDR[2])
						1'b0	: begin AXI_WSTRB = 8'b00001111; end
						1'b1	: begin AXI_WSTRB = 8'b11110000; end
						default	: begin AXI_WSTRB = 8'b00000000; end
					endcase
					end
		4'd3	: begin AXI_WSTRB = 8'b11111111; end
		default	: begin AXI_WSTRB = 8'b00000000; end
	endcase
	end	

//-------------------------------------------------------------------------------------------------------------
//-----------------------------------------FIB直接输入到AMO操作模块的数据寄存器组-----------------------------
//	
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin      
		AMO_bo_data     <=  'd0;
		AMO_bo_awsize	<=  'd0;
		AMO_bo_awaddr   <=  'd0;
		AMO_bo_wstrb    <=  'd0;
		AMO_bo_CMD      <=  'd0;
		AMO_bo_ID       <=  'd0;
		AMO_bo_valid    <=  'd0;
		end
	else if(AMO_bo_valid && !AMO_ao_valid ) begin
		AMO_bo_data     <=  AMO_bo_data;
		AMO_bo_awsize	<=  AMO_bo_awsize;
		AMO_bo_awaddr   <=  AMO_bo_awaddr;
		AMO_bo_wstrb    <=  AMO_bo_wstrb;
		AMO_bo_CMD      <=  AMO_bo_CMD;
		AMO_bo_ID       <=  AMO_bo_ID;
		AMO_bo_valid    <=  AMO_bo_valid;
		end		
	else if(FIBi_V & (op_AMOSWAP|op_AMOADD|op_AMOXOR|op_AMOAND|op_AMOOR|op_AMOMIN|op_AMOMAX|op_AMOMINU|op_AMOMAXU)) begin
		AMO_bo_data     <=  FIBi_DATA;
		AMO_bo_awsize	<=  FIBi_SIZE[2:0];
		AMO_bo_awaddr   <=  FIBi_ADDR;
		AMO_bo_wstrb    <=  AXI_WSTRB;
		AMO_bo_CMD      <=  {op_AMOSWAP,op_AMOADD,op_AMOXOR,op_AMOAND,op_AMOOR,op_AMOMIN,op_AMOMAX,op_AMOMINU,op_AMOMAXU};
		AMO_bo_ID       <=  FIBi_ID;
		AMO_bo_valid    <=  FIBi_V;
		end	
	else begin
		AMO_bo_data     <=  'd0;
		AMO_bo_awsize	<=  'd0;
		AMO_bo_awaddr   <=  'd0;
		AMO_bo_wstrb    <=  'd0;
		AMO_bo_CMD      <=  'd0;
		AMO_bo_ID       <=  'd0;
		AMO_bo_valid    <=  'd0;
		end
	end
	
//-------------------------------------------------------------------------------------------------------------
//-----------------------------------------AMO读操作返回的数据寄存器组----------------------------------------
//	
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		AMO_ao_data		<= 'd0;
		AMO_ao_valid	<= 'd0;
		end	
	else if(FIBi_AXI_rvalid && FIB_state == AMO_RB_s && FIBi_AXI_rresp == 2'b00) begin
		AMO_ao_data		<= FIBi_AXI_rdata;
		AMO_ao_valid	<= FIBi_AXI_rvalid;
		end
	else begin
		AMO_ao_data		<= 'd0;
		AMO_ao_valid	<= 'd0;
		end
	end

//-------------------------------------------------------------------------------------------------------------
//-----------------------------------------------AMO操作电路---------------------------------------------------
//
/*
由于AMO操作的位数是不确定的，有可能不足64位，在这中情况下，有效数据在AXI数据总线中的位置也是不确定的，在AMO操作时要特殊的处理
除去有符号的比大小，其他的操作可以通过strb对数据进行掩码后无脑的进行操作
有符号数的比大小，先通过地址来判断符号位的位置，再无脑的比大小就可以
*/

assign sourse1 = {((AMO_bo_wstrb[7])? AMO_bo_data[63:56]:8'd0),((AMO_bo_wstrb[6])? AMO_bo_data[55:48]:8'd0),((AMO_bo_wstrb[5])? AMO_bo_data[47:40]:8'd0),((AMO_bo_wstrb[4])? AMO_bo_data[39:32] :8'd0),
				  ((AMO_bo_wstrb[3])? AMO_bo_data[31:24]:8'd0),((AMO_bo_wstrb[2])? AMO_bo_data[23:16]:8'd0),((AMO_bo_wstrb[1])? AMO_bo_data[15:8] :8'd0),((AMO_bo_wstrb[0]) ? AMO_bo_data[7:0]	:8'd0)};
assign sourse2 = {((AMO_bo_wstrb[7])? AMO_ao_data[63:56]:8'd0),((AMO_bo_wstrb[6])? AMO_ao_data[55:48]:8'd0),((AMO_bo_wstrb[5])? AMO_ao_data[47:40]:8'd0),((AMO_bo_wstrb[4])? AMO_ao_data[39:32] :8'd0),
				  ((AMO_bo_wstrb[3])? AMO_ao_data[31:24]:8'd0),((AMO_bo_wstrb[2])? AMO_ao_data[23:16]:8'd0),((AMO_bo_wstrb[1])? AMO_ao_data[15:8] :8'd0),((AMO_bo_wstrb[0]) ? AMO_ao_data[7:0]	:8'd0)};

//检测数据的符号

always@(*) begin
	case(AMO_bo_awsize)
		3'd3	: begin
					case(AMO_bo_awaddr[2:0])
						3'd0	: begin sourse1_Symbol = sourse1[7]; end
						3'd1	: begin sourse1_Symbol = sourse1[15]; end
						3'd2	: begin sourse1_Symbol = sourse1[23]; end
						3'd3	: begin sourse1_Symbol = sourse1[31]; end
						3'd4	: begin sourse1_Symbol = sourse1[39]; end
						3'd5	: begin sourse1_Symbol = sourse1[47]; end
						3'd6	: begin sourse1_Symbol = sourse1[55]; end
						3'd7	: begin sourse1_Symbol = sourse1[63]; end
						default	: begin sourse1_Symbol = 1'b0; end
					endcase
					end
		3'd4	: begin 
					case(AMO_bo_awaddr[2:1]) 
						2'd0	: begin sourse1_Symbol = sourse1[15]; end
						2'd1	: begin sourse1_Symbol = sourse1[31]; end
						2'd2	: begin sourse1_Symbol = sourse1[47]; end
						2'd3	: begin sourse1_Symbol = sourse1[63]; end
						default	: begin sourse1_Symbol = 1'b0; end
					endcase
					end
		3'd5	: begin
					case(AMO_bo_awaddr[2])
						1'b0	: begin sourse1_Symbol = sourse1[31]; end
						1'b1	: begin sourse1_Symbol = sourse1[63]; end
						default	: begin sourse1_Symbol = 1'b0; end
					endcase
					end
		3'd6	: begin sourse1_Symbol = sourse1[63]; end
		default	: begin sourse1_Symbol = 1'b0; end
	endcase
	end	
	
always@(*) begin
	case(AMO_bo_awsize)
		3'd3	: begin
					case(AMO_bo_awaddr[2:0])
						3'd0	: begin sourse2_Symbol = sourse2[7]; end
						3'd1	: begin sourse2_Symbol = sourse2[15]; end
						3'd2	: begin sourse2_Symbol = sourse2[23]; end
						3'd3	: begin sourse2_Symbol = sourse2[31]; end
						3'd4	: begin sourse2_Symbol = sourse2[39]; end
						3'd5	: begin sourse2_Symbol = sourse2[47]; end
						3'd6	: begin sourse2_Symbol = sourse2[55]; end
						3'd7	: begin sourse2_Symbol = sourse2[63]; end
						default	: begin sourse2_Symbol = 1'b0; end
					endcase
					end
		3'd4	: begin 
					case(AMO_bo_awaddr[2:1]) 
						2'd0	: begin sourse2_Symbol = sourse2[15]; end
						2'd1	: begin sourse2_Symbol = sourse2[31]; end
						2'd2	: begin sourse2_Symbol = sourse2[47]; end
						2'd3	: begin sourse2_Symbol = sourse2[63]; end
						default	: begin sourse2_Symbol = 1'b0; end
					endcase
					end
		3'd5	: begin
					case(AMO_bo_awaddr[2])
						1'b0	: begin sourse2_Symbol = sourse2[31]; end
						1'b1	: begin sourse2_Symbol = sourse2[63]; end
						default	: begin sourse2_Symbol = 1'b0; end
					endcase
					end
		3'd6	: begin sourse2_Symbol = sourse2[63]; end
		default	: begin sourse2_Symbol = 1'b0; end
	endcase
	end	

//AMO运算电路

assign data_AMOSWAP = sourse1;
assign data_AMOADD = sourse1 + sourse2;
assign data_AMOXOR =  sourse1 ^ sourse2;
assign data_AMOAND = sourse1 & sourse2;
assign data_AMOOR =  sourse1 | sourse2;
assign data_AMOMIN = ((sourse1_Symbol & !sourse2_Symbol) || (sourse1_Symbol == sourse2_Symbol && sourse1 < sourse2)) ? sourse1 : sourse2;
assign data_AMOMAX = ((sourse1_Symbol & !sourse2_Symbol) || (sourse1_Symbol == sourse2_Symbol && sourse1 < sourse2)) ? sourse2 : sourse1;
assign data_AMOMINU = (sourse1 < sourse2) ? sourse1 : sourse2;
assign data_AMOMAXU = (sourse1 < sourse2) ? sourse2 : sourse1;

assign result1 = (AMO_bo_CMD[8]   ? data_AMOSWAP : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[7]   ? data_AMOADD  : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[6]   ? data_AMOXOR  : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[5]   ? data_AMOAND  : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[4]   ? data_AMOOR   : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[3]   ? data_AMOMIN  : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[2]   ? data_AMOMAX  : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[1]   ? data_AMOMINU : {`XLEN{1'b0}}) |
				 (AMO_bo_CMD[0]   ? data_AMOMAXU : {`XLEN{1'b0}}) ;

assign result2 = sourse2;

//-------------------------------------------------------------------------------------------------------------
//-----------------------------------------AMO操作后返回到core的数据寄存器组-----------------------------------
//		
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		AMO_Feedback_ID 	<= 'd0;
		AMO_Feedback_data	<= 'd0;
		AMO_Feedback_valid	<= 'd0;
		end
	else if(AMO_ao_valid) begin
		AMO_Feedback_ID 	<= AMO_bo_ID;
		AMO_Feedback_data	<= result2;
		AMO_Feedback_valid	<= AMO_ao_valid;
		end		
	else begin
		AMO_Feedback_ID 	<= AMO_Feedback_ID;
		AMO_Feedback_data	<= AMO_Feedback_data;
		AMO_Feedback_valid	<= AMO_Feedback_valid;
		end	
	end
	
//-------------------------------------------------------------------------------------------------------------
//-----------------------------------------AMO操作后写入到memory的数据寄存器组-----------------------------------
//		
//
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		AMO_TX_data		<= 'd0;
		AMO_TX_awsize	<= 'd0;
		AMO_TX_awaddr	<= 'd0;
		AMO_TX_wstrb	<= 'd0;
		AMO_TX_ID		<= 'd0;
		AMO_TX_valid	<= 'd0;
		end
	else if(AMO_ao_valid) begin
		AMO_TX_data		<= result1;
		AMO_TX_awsize	<= AMO_bo_awsize;
		AMO_TX_awaddr	<= AMO_bo_awaddr;
		AMO_TX_wstrb	<= AMO_bo_wstrb;
		AMO_TX_ID		<= AMO_bo_ID;
		AMO_TX_valid	<= AMO_ao_valid;
		end	
	else if(FIB_state == AMO_WD_s)begin
		AMO_TX_data		<= 'd0;
		AMO_TX_awsize	<= 'd0;
		AMO_TX_awaddr	<= 'd0;
		AMO_TX_wstrb	<= 'd0;
		AMO_TX_ID		<= 'd0;
		AMO_TX_valid	<= 'd0;
		end
	else begin
		AMO_TX_data		<= AMO_TX_data;
		AMO_TX_awsize	<= AMO_TX_awsize;
		AMO_TX_awaddr	<= AMO_TX_awaddr;
		AMO_TX_wstrb	<= AMO_TX_wstrb;
		AMO_TX_ID		<= AMO_TX_ID;
		AMO_TX_valid	<= AMO_TX_valid;
		end
	end
//-------------------------------------------------------------------------------
//---------------------------FIB interface--------------------------------------
//	
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_ID 		<= 'd0;
		FIBo_RPL 		<= 'd0;
		FIBo_WREN 		<= 'd0;
		FIBo_DATA    	<= 'd0;
		end
	else if(FIBo_WREN && FIBi_FULL) begin
		FIBo_ID 		<= FIBo_ID;
		FIBo_RPL 		<= FIBo_RPL;
		FIBo_WREN 		<= FIBo_WREN;
		FIBo_DATA    	<= FIBo_DATA;
		end	
	else if(FIB_state == IDLE_s && op_DEC_ERR && FIBi_V) begin
		FIBo_ID 		<= FIBi_ID;
		FIBo_RPL 		<= 8'hf0;
		FIBo_WREN 		<= FIBi_V;
		FIBo_DATA    	<= 'd0;	
		end		
	else if(FIB_state == SFR_R_s || FIB_state == SFR_W_s ) begin
		FIBo_ID 		<= SFR_ID_reg;
		FIBo_RPL 		<= 8'h10;
		FIBo_WREN 		<= 1'b1;
		FIBo_DATA    	<= FIBi_SFRo_DATA;	
		end	
	else if(FIBi_AXI_bvalid) begin
			if(AMO_Feedback_valid && FIB_state == AMO_WB_s) begin
				FIBo_ID 		<= AMO_Feedback_ID;
				FIBo_RPL 		<= AXI_BRPL;
				FIBo_WREN 		<= FIBi_AXI_bvalid;
				FIBo_DATA    	<= AMO_Feedback_data;	
				end
			else begin
				FIBo_ID 		<= FIBi_AXI_bid;
				FIBo_RPL 		<= AXI_BRPL;
				FIBo_WREN 		<= FIBi_AXI_bvalid;
				FIBo_DATA    	<= 'd0;	
				end
			end
	else if(FIBi_AXI_rvalid && FIB_state != AMO_RB_s) begin
		FIBo_ID 		<= FIBi_AXI_rid;
		FIBo_RPL 		<= AXI_RRPL;
		FIBo_WREN 		<= FIBi_AXI_rvalid;
		FIBo_DATA    	<= FIBi_AXI_rdata;	
		end	
	else begin
		FIBo_ID 		<= 'd0;
		FIBo_RPL 		<= 'd0;
		FIBo_WREN 		<= 'd0;
		FIBo_DATA    	<= 'd0;
		end
	end
		
//FIBo_WREN_ready
always@(*) begin
	if(FIBi_AXI_rvalid | FIBi_AXI_bvalid) begin
		if(FIBo_WREN && FIBi_FULL) begin
			FIBo_WREN_ready = 1'b0;
			end
		else begin
			FIBo_WREN_ready = 1'b1;
			end
		end
	else begin
		FIBo_WREN_ready = 1'b0;
		end
	end

	
//FIBo_ACK 
always@(*) begin
	if(FIBi_V & !FIBi_FULL) begin
		case(FIB_state) 
			IDLE_s			: begin
								if(op_NOOP|op_SIGR|(op_SIGW && ((FIBi_ADDR & `SFR_ADDR_MASK) == `SFR_ADDR_SEG))|op_SEQR|op_WAPR|op_AMOR|op_LR|op_AMOSWAP|op_AMOADD|op_AMOXOR|op_AMOAND|op_AMOOR|op_AMOMIN|op_AMOMAX|op_AMOMINU|op_AMOMAXU|op_DEC_ERR) begin
									FIBo_ACK = 1'b1;
									end
								else begin
									FIBo_ACK = 1'b0;
									end
								end
			GENERAL_W_WD_S	:begin
								FIBo_ACK = FIBi_AXI_wready;
								end
			SEQW_WD_s		:begin
								FIBo_ACK = FIBi_AXI_wready & ~FIBo_AXI_wlast;
								end
			default			: begin
								FIBo_ACK = 1'b0;
								end
		endcase
		end
	else begin
		FIBo_ACK = 1'b0;
		end
	end

//-------------------------------------------------------------------------------------------
//------------------------------------SFR interface------------------------------------------
//	
//访问SFR寄存器	
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_SFRi_ADDR  <= 'd0;
		FIBo_SFRi_DATA	<= 'd0;
		FIBo_SFRi_CS	<= 'd0;
		FIBo_SFRi_WR	<= 'd0;
		SFR_ID_reg 		<= 'd0;
		end
	else if(FIBi_V && (FIB_state == IDLE_s) && (op_SIGW || op_SIGR) && (FIBi_ADDR & `SFR_ADDR_MASK) == `SFR_ADDR_SEG) begin
		FIBo_SFRi_ADDR  <= FIBi_ADDR;
		FIBo_SFRi_DATA	<= FIBi_DATA;
		FIBo_SFRi_CS	<= FIBi_V;
		FIBo_SFRi_WR	<= !op_SIGR;
		SFR_ID_reg 		<= FIBi_ID;
		end
	else begin
		FIBo_SFRi_ADDR  <= 'd0;
		FIBo_SFRi_DATA	<= 'd0;
		FIBo_SFRi_CS	<= 'd0;
		FIBo_SFRi_WR	<= 'd0;
		SFR_ID_reg 		<= 'd0;
		end
	end
//---------------------------------------------------------------------------------
//------------------------------- AXI interface ----------------------------------- 
//
//-------------------写地址通道---------------------
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_AXI_awid 		<= 'd0;
		FIBo_AXI_awaddr 	<= 'd0;
		FIBo_AXI_awlen 		<= 'd0;
		FIBo_AXI_awsize 	<= 'd0;
		FIBo_AXI_awburst 	<= 'd0;
//		FIBo_AXI_awlock 	<= 'd0;
//		FIBo_AXI_awcache 	<= 'd0;
//		FIBo_AXI_awprot 	<= 'd0;
//		FIBo_AXI_awqos 		<= 'd0;
//		FIBo_AXI_awregion 	<= 'd0;
		FIBo_AXI_awvalid 	<= 'd0;
		end
	else if(FIBo_AXI_awvalid & !FIBi_AXI_awready) begin
		FIBo_AXI_awid 		<= FIBo_AXI_awid;
		FIBo_AXI_awaddr 	<= FIBo_AXI_awaddr;
		FIBo_AXI_awlen 		<= FIBo_AXI_awlen;
		FIBo_AXI_awsize 	<= FIBo_AXI_awsize;
		FIBo_AXI_awburst 	<= FIBo_AXI_awburst;
//		FIBo_AXI_awlock		<= FIBo_AXI_awlock;
//		FIBo_AXI_awcache 	<= FIBo_AXI_awcache;
//		FIBo_AXI_awprot 	<= FIBo_AXI_awprot;
//		FIBo_AXI_awqos 		<= FIBo_AXI_awqos;
//		FIBo_AXI_awregion 	<= FIBo_AXI_awregion;
		FIBo_AXI_awvalid 	<= FIBo_AXI_awvalid;
		end
	else if(FIB_state == AMO_WA_s) begin			//AMO_TX
		FIBo_AXI_awid 		<= AMO_TX_ID;
		FIBo_AXI_awaddr 	<= AMO_TX_awaddr;
		FIBo_AXI_awlen 		<= 'd0;
		FIBo_AXI_awsize 	<= AMO_TX_awsize;
		FIBo_AXI_awburst 	<= 2'b01;
//		FIBo_AXI_awlock 	<= 1'b0;
//		FIBo_AXI_awcache 	<= AXI_AXCACHE;					
//		FIBo_AXI_awprot 	<= AXI_AXPROT;
//		FIBo_AXI_awqos 		<= AXI_AXQOS;
//		FIBo_AXI_awregion 	<= AXI_AXREGION;
		FIBo_AXI_awvalid 	<= AMO_TX_valid;		
		end
	else if(FIB_WA_access) begin				//FIB
		FIBo_AXI_awid 		<= FIBi_ID;
		FIBo_AXI_awaddr 	<= FIBi_ADDR;
		FIBo_AXI_awlen 		<= FIBo_AXI_axlen_tem;
		FIBo_AXI_awsize 	<= FIBi_SIZE[2:0];
		FIBo_AXI_awburst 	<= FIBo_AXI_axburst_tem;
//		FIBo_AXI_awlock 	<= FIBo_AXI_axlock_tem;
//		FIBo_AXI_awcache 	<= AXI_AXCACHE;					
//		FIBo_AXI_awprot 	<= AXI_AXPROT;
//		FIBo_AXI_awqos 		<= AXI_AXQOS;
//		FIBo_AXI_awregion 	<= AXI_AXREGION;
		FIBo_AXI_awvalid 	<= FIBi_V;		
		end	
	else begin
		FIBo_AXI_awid 		<= 'd0;
		FIBo_AXI_awaddr 	<= 'd0;
		FIBo_AXI_awlen 		<= 'd0;
		FIBo_AXI_awsize 	<= 'd0;
		FIBo_AXI_awburst 	<= 'd0;
//		FIBo_AXI_awlock 	<= 'd0;
//		FIBo_AXI_awcache 	<= 'd0;
//		FIBo_AXI_awprot 	<= 'd0;
//		FIBo_AXI_awqos 		<= 'd0;
//		FIBo_AXI_awregion 	<= 'd0;
		FIBo_AXI_awvalid 	<= 'd0;
		end
	end

//--------------------写数据通道----------------------------	
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_AXI_wdata 		<= 'd0;
		FIBo_AXI_wstrb 		<= 'd0;
		FIBo_AXI_wlast 		<= 'd0;
		FIBo_AXI_wvalid    	<= 'd0;
		end
	else if(FIBo_AXI_wvalid & !FIBi_AXI_wready) begin
		FIBo_AXI_wdata 		<= FIBo_AXI_wdata;
		FIBo_AXI_wstrb 		<= FIBo_AXI_wstrb;
		FIBo_AXI_wlast 		<= FIBo_AXI_wlast;
		FIBo_AXI_wvalid    	<= FIBo_AXI_wvalid;
		end
	else if(FIB_state == AMO_WD_s) begin
		FIBo_AXI_wdata 		<= AMO_TX_data;
		FIBo_AXI_wstrb 		<= AMO_TX_wstrb;
		FIBo_AXI_wlast 		<= 1'b1;
		FIBo_AXI_wvalid    	<= AMO_TX_valid;
		end
	else if(FIB_WD_access) begin
		FIBo_AXI_wdata 		<= FIBi_DATA;
		FIBo_AXI_wstrb 		<= AXI_WSTRB;
		FIBo_AXI_wlast 		<= op_SIGR|op_SIGW|op_WAPR|op_WAPW|op_AMOR|op_AMOW|op_SEQE|op_LR|op_SC;
		FIBo_AXI_wvalid    	<= 1'b1;
		end
	else begin
		FIBo_AXI_wdata 		<= 'd0;
		FIBo_AXI_wstrb 		<= 'd0;
		FIBo_AXI_wlast 		<= 'd0;
		FIBo_AXI_wvalid    	<= 'd0;
		end
	end


//------------------------写回复通道--------------------------------
//AXI_BRPL
always@(*) begin
	if(SC_sent_flag && FIBi_AXI_bvalid && FIBi_AXI_bid == SC_sent_ID) begin
		if(FIBi_AXI_bresp == 2'b01) begin	//EXOKAY
			AXI_BRPL = 8'h10;
			end
		else begin
			AXI_BRPL = 8'hF0;
			end
		end
	else if(FIBi_AXI_bvalid)begin
		if(FIBi_AXI_bresp == 2'b00) begin	//OKAY
			AXI_BRPL = 8'h10;
			end
		else begin
			AXI_BRPL = 8'hF0;
			end
		end
	else begin
		AXI_BRPL = 'd0;
		end	
	end

//FIBo_AXI_bready
assign FIBo_AXI_bready = 1'b1;

//---------------------读地址通道----------------
always@(posedge CLKi or posedge RSTi) begin
	if(RSTi) begin
		FIBo_AXI_arid 		<= 'd0;
		FIBo_AXI_araddr 	<= 'd0;
		FIBo_AXI_arlen 		<= 'd0;
		FIBo_AXI_arsize 	<= 'd0;
		FIBo_AXI_arburst 	<= 'd0;
//		FIBo_AXI_arlock 	<= 'd0;
//		FIBo_AXI_arcache 	<= 'd0;
//		FIBo_AXI_arprot 	<= 'd0;
//		FIBo_AXI_arqos 		<= 'd0;
//		FIBo_AXI_arregion 	<= 'd0;
		FIBo_AXI_arvalid 	<= 'd0;
		end
	else if(FIBo_AXI_arvalid & !FIBi_AXI_arready) begin
		FIBo_AXI_arid 		<= FIBo_AXI_arid;
		FIBo_AXI_araddr 	<= FIBo_AXI_araddr;
		FIBo_AXI_arlen 		<= FIBo_AXI_arlen;
		FIBo_AXI_arsize 	<= FIBo_AXI_arsize;
		FIBo_AXI_arburst 	<= FIBo_AXI_arburst;
//		FIBo_AXI_arlock		<= FIBo_AXI_arlock;
//		FIBo_AXI_arcache 	<= FIBo_AXI_arcache;
//		FIBo_AXI_arprot 	<= FIBo_AXI_arprot;
//		FIBo_AXI_arqos 		<= FIBo_AXI_arqos;
//		FIBo_AXI_arregion 	<= FIBo_AXI_arregion;
		FIBo_AXI_arvalid 	<= FIBo_AXI_arvalid;
		end
	else if(FIB_RA_access) begin
		FIBo_AXI_arid 		<= FIBi_ID;
		FIBo_AXI_araddr 	<= FIBi_ADDR;
		FIBo_AXI_arlen 		<= FIBo_AXI_axlen_tem;
		FIBo_AXI_arsize 	<= FIBi_SIZE[2:0];
		FIBo_AXI_arburst 	<= FIBo_AXI_axburst_tem;
//		FIBo_AXI_arlock 	<= FIBo_AXI_axlock_tem;
//		FIBo_AXI_arcache 	<= AXI_AXCACHE;					
//		FIBo_AXI_arprot 	<= AXI_AXPROT;
//		FIBo_AXI_arqos 		<= AXI_AXQOS;
//		FIBo_AXI_arregion 	<= AXI_AXREGION;
		FIBo_AXI_arvalid 	<= FIBi_V;		
		end
	else begin
		FIBo_AXI_arid 		<= 'd0;
		FIBo_AXI_araddr 	<= 'd0;
		FIBo_AXI_arlen 		<= 'd0;
		FIBo_AXI_arsize 	<= 'd0;
		FIBo_AXI_arburst 	<= 'd0;
//		FIBo_AXI_arlock 	<= 'd0;
//		FIBo_AXI_arcache 	<= 'd0;
//		FIBo_AXI_arprot 	<= 'd0;
//		FIBo_AXI_arqos 		<= 'd0;
//		FIBo_AXI_arregion 	<= 'd0;
		FIBo_AXI_arvalid 	<= 'd0;
		end
	end

//----------------------读数据通道-------------------------

//AXI_RRPL
always@(*) begin
	if(FIBi_AXI_rvalid && LR_sent_flag && FIBi_AXI_rid == LR_sent_ID) begin
		if(FIBi_AXI_rresp == 2'b01) begin	//EXOKAY
			AXI_RRPL = 8'h10;
			end
		else begin
			AXI_RRPL = 8'hF0;
			end
		end
	else if(FIBi_AXI_rvalid)begin		
		if(FIBi_AXI_rresp == 2'b00) begin	
			if(FIBi_AXI_rlast) begin
				AXI_RRPL = 8'h10;			//OKAY
				end
			else begin
				AXI_RRPL = 8'h14;			//SEQ
				end
			end
		else begin
			AXI_RRPL = 8'hF0;
			end
		end
	else begin
		AXI_RRPL = 'd0;
		end
	end

assign FIBo_AXI_rready = FIBo_WREN_ready;


endmodule